package menus;

import beans.SessionManagedBean;
import com.icesoft.faces.component.menubar.MenuBar;
import com.icesoft.faces.component.menubar.MenuItem;
import java.util.ArrayList;
import java.util.List;
import javax.el.MethodExpression;
import javax.faces.bean.ManagedBean;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.MethodExpressionActionListener;
import lecture.Lecture;
import groups.ExerciseGroup;
import javax.faces.bean.CustomScoped;

/**
 *  The Menu Backend.
 *  It initialize the Menu and TODO: Listener anmelden auf englisch
 * @author Thorsten Ludwig
 */

@ManagedBean(name="menuBean")
@CustomScoped(value="#{window}")
public class MenuManagedBean {
    
    /**
     * backing for the MenuBar
     */
    private MenuBar menuBar;

    /**
     * All menu items
     */
    private List<MenuItem> menu;
    /**
     * the subitem containing the lectures
     */
    private MenuItem lectures;
    /**
     * the subitem containg the lectures, which are administrated
     * by the user
     */
    private MenuItem adminLectures;
    /**
     * the subitem containg all avaible subitems
     */
    private MenuItem allAvaibleLectures;
    /**
     * Creating a new menu with Parent items.
     */
    public MenuManagedBean() {
        this.menu = new ArrayList<MenuItem>();
        this.lectures = new MenuItem();
        this.lectures.setValue("Vorlesungen");

        this.adminLectures = new MenuItem();
        this.adminLectures.setValue("administrierte Vorlesungen");

        this.allAvaibleLectures = new MenuItem();
        this.allAvaibleLectures.setValue("Vorlesung belegen");

        MenuItem features = new MenuItem();
        features.setValue("Funktionen");

        MenuItem createLecture = new MenuItem();
        createLecture.setValue("Vorlesung erstellen");
        createLecture.setActionExpression(this.getActionExp("newLecture.jsf"));
        
        features.getChildren().add(createLecture);

        this.menu.add(lectures);
        this.menu.add(adminLectures);
        this.menu.add(allAvaibleLectures);
        this.menu.add(features);
        
    }

    public MenuBar getMenuBar() {
        return menuBar;
    }

    public void setMenuBar(MenuBar menuBar) {
        this.menuBar = menuBar;
    }
    
    public void lectureSelected(ActionEvent e) {
         FacesContext c = FacesContext.getCurrentInstance();
         SessionManagedBean sessionBean = c.getApplication().evaluateExpressionGet(c, "#{sessionBean}", SessionManagedBean.class);
         System.out.println("Menu Item selected");
         String actionFired = ((UIComponent) e.getSource()).getClientId(FacesContext.getCurrentInstance());
         actionFired = actionFired.substring(actionFired.lastIndexOf(":")+1);
         sessionBean.setSelectedLecture(actionFired);
    }

    /**
     * Adding a list of lectures
     * @param lectures An ArrayList of lectures
     */
    public void addLectures(List<Lecture> lectures) {
        MenuItem item;
        for (Lecture v: lectures) {
            item = new MenuItem();
            item.setValue(v.getInfo().getName());
            item.setId(v.getInfo().getLectureId());
            item.addActionListener(getActionListenerExp("#{menuBean.lectureSelected}"));
            item.setActionExpression(getActionExp("lecture.jsf"));
            this.lectures.getChildren().add(item);
        }
    }

    /**
     * Adding a single lecture
     * @param lecture the lecture
     */
    public void addLecture(Lecture lecture) {
        MenuItem item = new MenuItem();
        item.setValue(lecture.getInfo().getName());
        item.setId(lecture.getInfo().getLectureId());
        item.addActionListener(getActionListenerExp("#{menuBean.lectureSelected}"));
        item.setActionExpression(getActionExp("lecture.jsf"));
        this.lectures.getChildren().add(item);
    }
    /**
     * Adding a list of avaible lectures
     * @param avaibleLectures list of avaible lectures
     */
    public void addAvaibleLectures (List<Lecture> avaibleLectures){
        this.allAvaibleLectures.getChildren().clear();
        MenuItem item;
        this.allAvaibleLectures.getChildren().clear();
        for (Lecture v: avaibleLectures) {
            item = new MenuItem();
            item.setValue(v.getInfo().getName());
            item.setId(v.getInfo().getLectureId());
            item.addActionListener(getActionListenerExp("#{menuBean.lectureSelected}"));
            item.setActionExpression(getActionExp("lecture.jsf"));
            this.allAvaibleLectures.getChildren().add(item);
        }
    }

    /**
     * Adding a single, avaible lecture
     * @param avaibleLecture the avaible lecture
     */
    public void addAvaibleLecture(Lecture avaibleLecture) {
        MenuItem item = new MenuItem();
        item.setValue(avaibleLecture.getInfo().getName());
        item.setId(avaibleLecture.getInfo().getLectureId());
        item.addActionListener(getActionListenerExp("#{menuBean.lectureSelected}"));
        item.setActionExpression(getActionExp("lecture.jsf"));
        this.allAvaibleLectures.getChildren().add(item);
    }









    /**
     * Adding a list of administrated lectures
     * @param adminLectures list of administrated lectures
     */
    public void addAdminLectures (List<Lecture> adminLectures){
        this.adminLectures.getChildren().clear();
        MenuItem item;
        if (adminLectures == null)
            System.out.print("AdminLectures ist null!");
        for (Lecture v: adminLectures) {
            item = new MenuItem();
            item.setValue(v.getInfo().getName());
            this.adminLectures.getChildren().add(item);
        }
    }

    /**
     * Adding a single, administrated lecture
     * @param adminLecture the adminstrated lecture
     */
    public void addAdministratedLecture(Lecture administratedLecture) {
        MenuItem item = new MenuItem();
        item.setValue(administratedLecture.getInfo().getName());
        this.adminLectures.getChildren().add(item);
    }




    // Method to use when you want to get an Action method
     public MethodExpression getActionExp(String actionName){
         FacesContext context = FacesContext.getCurrentInstance();
         return context.getApplication().getExpressionFactory()
                 .createMethodExpression(context.getELContext(), actionName, String.class, new Class[0]);
     }
     
     // Method to use when you want to get an ActionListener method
     public MethodExpressionActionListener getActionListenerExp(String actionListenerName){
         FacesContext context = FacesContext.getCurrentInstance();
         MethodExpression mExp = context.getApplication().getExpressionFactory()
                 .createMethodExpression(context.getELContext(), actionListenerName, null,
                 new Class[] {ActionEvent.class});
         return new MethodExpressionActionListener(mExp);
     }




    /**
     * returning the menu
     * @return the hole menu
     */
    public List<MenuItem> getMenu() {
        return this.menu;
    }
}